import CryptoJs from 'crypto-js';


export const DESENSITIZE_TYPE = {
  CHINESE_NAME: "名字",
  ID_CARD: "身份证",
  FIXED_PHONE: "固定电话",
  MOBILE_PHONE: "手机号码",
  ADDRESS: "地址",
  EMAIL: "邮箱",
  CAR_LICENSE: "车牌号",
  BANK_CARD: "银行卡号",
  IPV4: "IPV4",
  IPV6: "IPV6"
}
const hide = (str, startInclude, endExclude) => {
  return replace(str, startInclude, endExclude, '*');
}

const  isBlank = (str) => !str || /^\s*$/.test(str);

const replace = (str, startInclude, endExclude, replacedChar) => {
  if (!str || str.length === 0) {
    return str;
  }
  const originalStr = str;
  const strLength = Array.from(originalStr).length;
  if (startInclude > strLength) {
    return originalStr;
  }
  if (endExclude > strLength) {
    endExclude = strLength;
  }
  if (startInclude > endExclude) {
    return originalStr;
  }

  let result = '';
  for (let i = 0; i < strLength; i++) {
    if (i >= startInclude && i < endExclude) {
      result += replacedChar;
    } else {
      result += Array.from(originalStr)[i];
    }
  }
  return result;
};

const firstMask = (str) => {
  if (isBlank(str)) {
    return "";
  }
  return hide(str, 1, str.length);
}

const chineseName = (fullName) => {
  return firstMask(fullName);
}

const idCardNum = (idCardNum, front, end) => {
  if (isBlank(idCardNum)) {
    return "";
  }
  if ((front + end) > idCardNum.length) {
    return idCardNum;
  }
  if (front < 0 || end < 0) {
    return idCardNum;
  }
  return hide(idCardNum, front, idCardNum.length - end);
}

const fixedPhone = (num) => {
  if (isBlank(num)) {
    return "";
  }
  return hide(num, 4, num.length - 2);
}

const mobilePhone = (num) => {
  if (isBlank(num)) {
    return "";
  }
  return hide(num, 3, num.length - 4);
}

const address = (address, size) => {
  if (isBlank(address)) {
    return "";
  }
  let length = address.length;
  return hide(address, length - size, length);
}

const email = (mail) => {
  if (isBlank(address)) {
    return "";
  }
  const index = mail.indexOf('@');
  if (index === -1) {
    return mail;
  }
  return hide(mail, 1, index);
}

const carLicense = (carLicense) => {
  if (isBlank(carLicense)) {
    return "";
  }
  if (carLicense.length === 7) {
    return hide(carLicense, 3, 6);
  } else if (carLicense.length === 8) {
    return hide(carLicense, 3, 7);
  }
  return carLicense;
}

const bankCard = (bankCard) => {
  if (isBlank(bankCard)) {
    return "";
  }
  const bankCardWithoutBlank = bankCard.replace(/\s*/g,"");
  if (bankCardWithoutBlank.length < 9) {
    return bankCard;
  }
  let length = bankCardWithoutBlank.length;
  let endLength = length % 4 === 0 ? 4: length%4;
  let midLength = length - 4 - endLength;

  let result = bankCardWithoutBlank.substring(0, 4);
  for (let i = 0; i< midLength; i++) {
    if (i % 4 === 0) {
      result += ' ';
    }
    result += "*";
  }
  return result + " " + bankCardWithoutBlank.substring(length - endLength, length);
}

const subBefore = (string, separator) => {
  if (isBlank(string)) {
    return "";
  }
  let index = string.indexOf(separator);
  if (index === -1) {
    return string;
  }
  return string.substring(0, index);
}

const ipv4 = (ip) => {
  return subBefore(ip, ".") + ".*.*.*";
}

const ipv6 = (ip) => {
  return subBefore(ip, ":") + ":*:*:*:*:*:*:*";
}

export const desensitized = (str, desensitizeType) => {
  if (!str) {
    return "";
  }
  switch (desensitizeType) {
    case DESENSITIZE_TYPE.CHINESE_NAME:
      return chineseName(str);
    case DESENSITIZE_TYPE.ID_CARD:
      return idCardNum(str, 1, 2);
    case DESENSITIZE_TYPE.FIXED_PHONE:
      return fixedPhone(str);
    case DESENSITIZE_TYPE.MOBILE_PHONE:
      return mobilePhone(str);
    case DESENSITIZE_TYPE.ADDRESS:
      return address(str, 8);
    case DESENSITIZE_TYPE.EMAIL:
      return email(str);
    case DESENSITIZE_TYPE.CAR_LICENSE:
      return carLicense(str);
    case DESENSITIZE_TYPE.BANK_CARD:
      return bankCard(str);
    case DESENSITIZE_TYPE.IPV4:
      return ipv4(str);
    case DESENSITIZE_TYPE.IPV6:
      return ipv6(str);
    default:
      return str;
  }
}


export const encryptCbc = (password, data) => CryptoJs.AES.encrypt(data, password.toLowerCase()).toString();
export const decryptCbc = (password, encrypted) => {
  let result;
  try {
    result = CryptoJs.AES.decrypt(encrypted, password.toLowerCase()).toString(CryptoJs.enc.Utf8)
  } catch (error) {
    result = encrypted;
  }
  return result;
}
